home *** CD-ROM | disk | FTP | other *** search
-
- /***********************************************************************/
-
- /* File KREC.C - Receive-procedures for RML Kermit;
- Chris Kennington, RML. 9th July 1985. */
-
- #define DEFS1 1
- #define DEFS2 1
- #define DEFS4 1
-
- #include "stdio.h"
- #include "b:kext.h"
-
- static char *ptr2; /* Pointer to converted file name */
- static int len;
-
-
-
- char cpmunge(len,new,old)
- /* Convert supplied name to a (similar) one which is legal
- * for CP/M; all alphabetics to upper case, all punctuation
- * deleted except for a single dot (the first if more than
- * one in input), colon taken as restarting the munge, all
- * controls deleted, length limited to 8.3, if input is
- * > 8 without a dot, dot inserted and next 3 chars used
- * as suffix. Munge terminated by 0 as a C-string.
- * Returns length of munged name (not including terminating 0). */
- char *old, *new;
- int len;
- {
- char c, i, j, p2, dotty;
-
- j = p2 = dotty = 0;
- for (i=0; i<len; ++i) { /* step thro' old */
- /* unwanted chars, continue the loop; wanted chars, store at end. */
- if (p2 > 3)
- goto Exit; /* suffix full */
- c = old[i] & 0x7f;
- if (c > '@') { /* ordinaries */
- c &= 0x5f; /* upper case */
- if (c > 0x5a)
- continue; /* illegal chars */
- }
- else if (c > SP) switch(c) { /* punctuation & numerals */
- case'0': /* accept all numerals */
- case'1':
- case'2':
- case'3':
- case'4':
- case'5':
- case'6':
- case'7':
- case'8':
- case'9':
- case'$':
- break;
-
- case ':': /* previous was disk-letter */
- j = 0; /* start afresh */
- dotty = 0;
- continue;
- case '.': /* CP/M divider */
- if (dotty != 0)
- continue; /* two dots illegal */
- if (j == 0)
- continue; /* leading dot illegal */
- ++dotty;
- break;
- default: /* all others ignored */
- continue;
- } /* end else-if-switch */
- else /* controls etc. */
- continue;
- /* anything that reaches here must be stored */
- if (dotty == 0) { /* in main name */
- if (j > 7) { /* but it's full */
- ++dotty;
- new[j++] = '.'; /* rest as suffix */
- ++p2;
- } }
- else /* in suffix */
- ++p2;
- new[j++] = c;
- } /* end for */
- if (j == 0) { /* no valid chars in "old" */
- strcpy(new,DEFNAM); /* so replace with default */
- j = DEFLEN; /* length of default */
- }
- Exit:
- new[j] = 0; /* close as string */
- return(j);
- } /* end of cpmunge() */
-
-
-
- char rdata() /* Receive Data */
- {
- int fail, num;
- char typ;
-
- if (numtry++ > MAXTRY)
- return('A'); /* abort if too many tries */
-
- typ = rpack(&len,&num,recpkt);
- switch(typ) {
-
- case 'D': /* Data */
- if (num != n) { /* not right packet */
- if (oldtry++ > MAXTRY)
- return('A');
- if (num == ((n==0) ? 63:n-1)) {
- spack('Y',num,0,0); /* re-ACK previous */
- numtry = 0;
- if (list == 1)
- outc('D');
- if (list > 2)
- printf("\rDbg: Duplicate (%c).",tochar(num));
- return(state); /* Don't write out data! */
- }
- else return('A'); /* sorry, wrong number */
- }
- if ( (fail = bufemp(recpkt,len)) != 0 ) {
- error(diskfail,fail);
- return('A');
- }
- spack('Y',n,0,0);
- inctry(); /* ++n%64 & mod tries */
- return('D'); /* Remain in data state */
-
- case 'F': /* Got a File Header */
- case 'X': /* or a text header */
- if (oldtry++ > MAXTRY)
- return('A'); /* If too many tries, "abort" */
- if (num == ((n==0) ? 63:n-1)) {
- spack('Y',num,0,0); /* ACK previous again */
- numtry = 0;
- return(state); /* Stay in Data state */
- }
- else return('A'); /* Not previous packet, "abort" */
-
- case 'Z': /* End-Of-File */
- if (num != n)
- return('A');
- if (fp != 0)
- printmsg("** File <%s> received. ",ptr2);
- kclose(fp); /* Close the file */
- spack('Y',n,0,0);
- fp = 0;
- n = (n+1)%64;
- return('F'); /* Go back to Receive File state */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt);
- reclose();
- return('A'); /* abort */
-
- case 'A': /* user aborted transfer */
- recfail();
- reclose();
- return('A');
-
- case FALSE: /* Didn't get packet */
- spack('N',n,0,0);
- return(state); /* Keep trying */
-
- default: /* Some other; abort */
- error(badmsg,'D',typ);
- return('A');
- }
- } /* end of rdata() */
-
-
-
- static recfail() /* process user abort */
- {
- char num;
-
- abtflag = 0;
- rpack(&len,&num,recpkt); /* wait for next packet */
- error(errmsg); /* then abort */
- return;
- } /* end of recfail() */
-
-
-
- static reclose() /* close file if open */
- {
- if (fp != 0) {
- kclose(fp);
- fp = 0;
- printmsg("File <%s> partially received; last data was:",ptr2);
- oldpkt[len] = 0;
- printf("\r \"%s\". ",oldpkt);
- }
- return;
- } /* end of reclose() */
-
-
-
- recsw(ist,ipkt) /* Receive files. */
- int ist; /* initial state */
- char ipkt; /* initial packet-type */
- {
- fp = 0;
- numtry = 0;
- state = ist;
-
- forever {
- if (list > 2) {
- outc(CR);
- printf("Dbg: recsw() state: %c",state);
- }
- errdisp();
- if (abtflag != 0) {
- recfail();
- reclose();
- return(FALSE);
- } /* catch user aborts during spack() */
- switch(state) {
-
- /* special initial states (message already in packet[]):- */
- case RMH: /* send command and display */
- case RMSV: /* anything sent back */
- case GET: /* get files */
- spack(ipkt,n,strlen(packet),packet);
- state = rinit();
- break;
-
- /* normal staes during reception:- */
- case 'R':
- state = rinit();
- break; /* Receive-Init */
- case 'F':
- state = rfile();
- break; /* Receive-File */
- case 'D':
- state = rdata();
- break; /* Receive-Data */
- case 'C':
- reclose();
- return(TRUE); /* Complete state */
- case 'A':
- reclose();
- return(FALSE); /* "Abort" state */
- } }
- } /* end of recsw() */
-
-
-
- char rfile() /* Receive File Header */
- {
- char disk, *ptr1;
- int num;
-
- if (numtry++ > MAXTRY)
- return('A');
-
- switch(rpack(&len,&num,recpkt)) {
-
- case 'S': /* Send-Init, maybe our ACK lost */
- if (oldtry++ > MAXTRY)
- return('A');
- if (num == ((n==0) ? 63:n-1)) { /* Previous packet? */
- len = spar(packet);
- spack('Y',num,len,packet);
- numtry = 0;
- return(state);
- }
- else return('A'); /* Not previous packet, "abort" */
-
- case 'Z': /* End-Of-File */
- if (oldtry++ > MAXTRY) return('A');
- if (num == ((n==0) ? 63:n-1)) { /* Previous packet? */
- spack('Y',num,0,0);
- numtry = 0;
- return(state);
- }
- else return('A'); /* Not previous packet, "abort" */
-
- case 'F': /* File Header */
- if (num != n)
- return('A');
- vtline(LOCFILE,filblank);
- ptr2 = fname + 2; /* leave room for disk-letter */
- cpmunge(len,ptr2,recpkt); /* validate file name received */
- if (filecount) { /* if override name or disk */
- disk = 0;
- ptr1 = *filelist;
- if (*(ptr1+1) == ':') { /* if disk-letter present */
- disk = *ptr1;
- ptr1 += 2; /* up to start of filename */
- }
- if (*ptr1 != 0) { /* if filename present */
- cpmunge(strlen(ptr1),ptr2,ptr1);
- --filecount; /* substitute for name received */
- ++filelist; /* & advance parm-counters */
- }
- if (disk != 0) { /* if disk-letter specified */
- *(--ptr2) = ':'; /* put it into fname */
- *(--ptr2) = disk; /* in front of filename */
- } } /* end if, if */
- /* fname[] now contains correct validated name, including any disk-letter,
- and ptr2 => either its beginning or third char. */
- vtline(LOCFILE,ptr2);
- s4sleep();
- if ( (ptr1 = avoid(ptr2)) != 0 ) {
- error(ptr1,ptr2);
- return('A');
- }
- if ((fp=kwopen(ptr2))==NULL) {
- error("Cant create <%s> - cancelled",ptr2);
- return('A');
- }
- else
- printmsg("Receiving <%s> as <%s>\r",recpkt,ptr2);
- spack('Y',n,0,0);
- inctry(); /* ++n%64 & mod tries */
- return('D'); /* Switch to Data state */
-
- case 'Y': /* short reply */
- recpkt[*len] = 0;
- printmsg("%s\r%s", mainsays,recpkt);
- return('C');
-
- case 'X': /* long reply */
- vtline(LOCFILE,mainsays);
- printmsg("%s\r",mainsays);
- spack('Y',n,0,0);
- inctry();
- return('D');
-
- case 'B': /* Break transmission (EOT) */
- if (num != n)
- return ('A');
- spack('Y',n,0,0);
- return('C'); /* Go to complete state */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt);
- return('A');
-
- case 'A': /* user aborted transfer */
- return('A');
-
- case FALSE: /* Didn't get packet */
- if (list != 1)
- txtout(trying);
- spack('N',n,0,0);
- return(state);
-
- default: /* Some other type, abort */
- error(badmsg,'F',type);
- return('A');
- }
- } /* end of rfile() */
-
-
-
-
- char rinit() /* Receive Initialization */
- {
- int num;
-
- /* unlimited retries in this state */
- switch(rpack(&len,&num,recpkt))
- {
- case 'S': /* Send-Init */
- n = num; /* accept their number */
- rpar(recpkt,len);
- len = spar(packet);
- spack('Y',n,len,packet);
- compmode();
- inctry(); /* ++n%64 & mod tries */
- return('F');
-
- case 'I': /* Info-exchange */
- rpar(recpkt,len);
- len = spar(packet);
- spack('Y',n,len,packet);
- compmode();
- return('R');
-
- case 'Y': /* short reply */
- recpkt[*len] = 0;
- printmsg("%s\r%s", mainsays,recpkt);
- return('C');
-
- case 'X': /* long reply */
- vtline(LOCFILE,mainsays);
- printmsg("%s\r",mainsays);
- n = num;
- spack('Y',n,0,0);
- inctry();
- return('D');
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt);
- case 'N': /* NAK */
- return('A');
-
- case 'A': /* User abort */
- return('A');
-
- case FALSE: /* Didn't get packet */
- if (list != 1)
- txtout(trying);
- if (state == 'R') /* normal receive */
- spack('N',n,0,0);
- return(state);
-
- default: /* Some other type, abort */
- error(badmsg,'S',type);
- return('A');
- }
- } /* end of rinit() */
-
-
-
- /************ END of file KREC.C ***************************/
-